package com.rd.teacher.jichao.day15.producer2_2;

import java.util.LinkedList;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

// 容器 缓冲区
public class Container {

    LinkedList<Integer> list = new LinkedList<>();
    // 容量
    int capacity = 10;

    ReentrantLock lock = new ReentrantLock();
    // 通过lock获取条件变量
    Condition prodCondition = lock.newCondition();
    Condition consCondition = lock.newCondition();

    public void put(int value) {
        // 如果在这儿需要sleep 因为sleep不会释放锁
        // 所以需要在synchronized外层来sleep

        lock.lock();
        // 当容器满了  需要阻塞等待
        while (list.size() == capacity) {
            System.out.println("full,waiting");
            try {
                prodCondition.await();
//                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        // 如果没有满  继续添加元素
        list.offer(value);
        System.out.println(Thread.currentThread().getName()
                + " put " + value);
        // 如果队列为空时  会有消费者等待数据
        // 所以在添加数据后  需要唤醒可能等待数据的消费者
        consCondition.signalAll();

        lock.unlock();
    }

    public Integer take() {
        Integer value = 0;
        // 判断容器中是否存在数据

        lock.lock();
        // 如果没有元素 等待
        while (list.size() == 0) {
            System.out.println("empty,waiting");
            try {
                consCondition.await();
//                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        // 如果有数据 继续取出队首元素
        value = list.poll();
        System.out.println(Thread.currentThread().getName()
                + " take " + value);
        prodCondition.signalAll();

        lock.unlock();
        return value;
    }

}
